<?php
/**
 * Created by PhpStorm.
 * User: admin
 * Date: 2018/6/13
 * Time: 23:24
 */

namespace app\common\model;

use app\common\cachemodel\ZlUserVip;
use app\common\lib\exception\ApiException;
use think\Cache;
use XznsTools\cache\CacheManage;

/**
 * 文章评论回复相关模型
 * Class ArticleCommentReply
 * @package app\common\model
 */
class ArticleCommentReply extends Base
{
    protected $table = 'wechatadmin.system_comment_reply';

    const COMMENT_REPLY_ID = 'comment_reply_id_'; //相关评论的所有回复id
    const COMMENT_REPLY = 'comment:reply:'; //回复详情缓存键名
    const USER_REPLY_ID = 'user:reply:'; //当前用户所有回复id
    const READ_REPLY = 'read_reply_'; //已读回复的缓存键名
    const REPLY_LEVEL_NICKNAME = 'reply_level_nickname_'; //相关回复上级用户名称
    const CACHE_TIME = 86400 * 3;

    /**
     * 获取当前评论的回复列表
     * @param array $map
     * @param int $page
     * @param bool $is_list
     * @return array
     */
    public function getReplyLists($map = [], $page = 1, $is_list = true)
    {
        return (new \app\common\cachemodel\ArticleCommentReply())->getPageCommentReplyList(null, $map['ac_id'], 1, $page);
        $ac_id = $map['ac_id'];  //评论id
        $reply_ids = false;

        if ($this->cache_on >= 1)
        {
            $reply_ids = Cache::get(self::COMMENT_REPLY_ID . $ac_id);// 获取当前评论回复id数组 -- 根据评论id
        }
        // 获取当前评论所有回复id
        if ($reply_ids === false)
        {
            try
            {
                $reply_id = $this->field('id')
                    ->where("comment_id=$ac_id AND status=0")
                    ->order('id DESC')
                    ->select();
                $reply_id = json_decode(json_encode($reply_id, true), true);

                // 将回复id组成字符串
                if (!empty($reply_id)) foreach ($reply_id as $acl) $reply_ids .= $acl['id'] . ',';

                // 缓存回复id -- 根据评论id
                if ($this->cache_on >= 1)
                    Cache::set(self::COMMENT_REPLY_ID . $ac_id, $reply_ids, self::CACHE_TIME);
            }
            catch (\Exception $e)
            {
                $reply_ids = '';// 回复为空
            }
        }

        // 将回复id转为数组
        $reply_ids = explode(',', $reply_ids);

        if ($is_list)
        {
            $per_page = 10;// 当前评论回复每页显示数量
        } else
        {
            $per_page = 3;// 当前评论回复每页显示数量
        }
        // 去除数组最后一个元素
        array_pop($reply_ids);

        // 统计有多少回复
        $total = count($reply_ids);
        //获取分页信息
        $data_list = getPaginatorData($total, $page, $per_page);

        //获取分页后的回复id数组
        $comment_reply = array_slice($reply_ids, $data_list['start'], $data_list['end']);

        unset($data_list['start']);
        unset($data_list['end']);

        // 根据当前页评论id获取所需的评论内容
        if (!empty($comment_reply))
        {
            $ac_ids = '';
            $temp = [];

            // 获取缓存回复内容,根据回复id
            foreach ($comment_reply as $ac_id)
            {
                if ($this->cache_on >= 1)
                {
                    // 获取当前评论下的回复内容
                    $temp[$ac_id] = Cache::get(self::COMMENT_REPLY . $ac_id);
                } else
                {
                    $temp[$ac_id] = false;
                }
                // 回复内容未缓存，等待从数据库中获取
                if ($temp[$ac_id] === false)
                {
                    unset($temp[$ac_id]);
                    $ac_ids .= ',' . $ac_id;
                }
            }

            // 从数据库获取回复内容
            if ($ac_ids != '' || strlen($ac_ids) > 0)
            {
                // 去掉开头的 ,
                $ac_ids = substr($ac_ids, 1);

                try
                {
                    $replys = $this
                        ->alias('cr')
                        // ->field('cr.id,cr.create_time,cr.content,cr.aid,cr.pid,a.title,
                        // u.nickname,u.avatar,
                        // u1.nickname nickname1,u1.avatar avatar1,ac.content content1,
                        // u2.nickname nickname2,u2.avatar avatar2,cr2.content content2')
                        ->field('cr.id,cr.create_time,cr.content,cr.aid,cr.pid,a.title,u.avatar,u.id uid,
                        u.nickname nickname1,u1.avatar avatar1,ac.content content1,
                        u2.nickname nickname2,u2.avatar avatar2,cr2.content content2')
                        ->join('wechatadmin.system_article_comment ac', 'cr.comment_id=ac.id', 'LEFT')
                        ->join('wechat_backup_07_18_14_43_00.app_user u1', 'ac.ucid=u1.uc_id', 'LEFT')
                        ->join('wechatadmin.system_comment_reply cr2', 'cr.pid=cr2.id', 'LEFT')
                        ->join('wechat_backup_07_18_14_43_00.app_user u2', 'cr2.ucid=u2.uc_id', 'LEFT')
                        ->join('wechatadmin.system_article a', 'cr.aid=a.id', 'LEFT')
                        ->join('wechat_backup_07_18_14_43_00.app_user u', 'cr.ucid=u.uc_id', 'LEFT')
                        ->where(['cr.id' => ['in', $ac_ids]])
                        ->order('cr.id DESC')
                        ->selectOrFail();
                    $replys = json_decode(json_encode($replys, true), true);

                }
                catch (\Exception $e)
                {
                    $replys = [];
                }
                if (!empty($replys))
                {
                    foreach ($replys as $k => $a)
                    {
                        $a['content'] = htmlspecialchars_decode($a['content']);
                        // 将回复内容缓存
                        if ($this->cache_on >= 1)
                            Cache::set(self::COMMENT_REPLY . $a['id'], $a, self::CACHE_TIME);
                        // 将数据库查出来的内容 写入到数组中为空的部分
                        $temp[$a['id']] = $a;
                    }
                }
            }

            krsort($temp);
            if (!empty($temp))
            {
                foreach ($temp as $k => $v)
                {
                    $v['vip'] = (isset($v['uid']) && $v['uid']) ? (new ZlUserVip())->getUserVipLevel($v['uid']) : 0;
                    unset($v['uid']);
                    $data_list['data'][] = $v;
                }
            }
        }

        return $data_list;
    }

    /**
     ** 获取当前用户的回复列表,回复我的  -- 根据用户id
     * @param array $map
     * @return array
     * @throws \Exception
     */
    public function reply_me($map = [])
    {
        $page = $map['page']; // 分页页码
        $uc_id = $map['uc_id'];
        $uid = $map['uid'];
        $reply_ids = false;

        // 获取用户未读信息
        $unread_ids = $this->getUnReadReply(['ucid' => $uc_id, 'uid' => $uid]);
        $unread_ids_arr = [];
        if ($unread_ids)
        {
            foreach ($unread_ids as $k => $v)
            {
                $unread_ids_arr[] = [
                    'reply_id' => $v,
                    'uid' => $uid,
                ];
            }
            //  回复我的消息全阅读
            $this->table('wechat_backup_07_18_14_43_00.app_user_reply')->insertAll($unread_ids_arr);
            CacheManage::getInstance()->setCacheConfig('user.read_reply', $map['uid'])->rmCache('list');
            Cache::rm('read_reply_' . $map['uid']);
        }
        //  获取回复我的数据
        if ($this->cache_on >= 1)
        {
            $reply_ids = Cache::get(self::USER_REPLY_ID . $uid);// 获取当前用户回复id数组
        }

        // 获取当前用户所有回复id
        if ($reply_ids === false)
        {
            try
            {
                $reply_id = $this
                    ->alias('cr')
                    ->field('cr.id')
                    ->join('wechatadmin.system_article_comment ac', 'cr.comment_id=ac.id', 'LEFT')
                    ->join('wechat_backup_07_18_14_43_00.app_user u1', 'ac.ucid=u1.uc_id', 'LEFT')
                    ->join('wechatadmin.system_comment_reply cr2', 'cr.pid=cr2.id', 'LEFT')
                    ->join('wechat_backup_07_18_14_43_00.app_user u2', 'cr2.ucid=u2.uc_id', 'LEFT')
                    ->join('wechatadmin.system_article a', 'cr.aid=a.id', 'LEFT')
                    ->join('wechat_backup_07_18_14_43_00.app_user u', 'cr.ucid=u.uc_id', 'LEFT')
                    ->where("u.forbidden=0 AND cr.status=0 AND ((cr.pid=0 AND ac.ucid='{$uc_id}' AND ac.status=0) OR (cr.pid>0 AND cr2.ucid='{$uc_id}' AND cr2.status=0))")
                    ->order('cr.id DESC')
                    ->selectOrFail();

                $reply_id = json_decode(json_encode($reply_id, true), true);

                // 将评论id组成字符串
                if (!empty($reply_id)) foreach ($reply_id as $acl) $reply_ids .= $acl['id'] . ',';
            }
            catch (\Exception $e)
            {
                $reply_ids = '';// 文章列表默认为空
            }
            // 缓存回复id,根据评论id
            if ($this->cache_on >= 1)
            {
                Cache::set(self::USER_REPLY_ID . $uid, $reply_ids, self::CACHE_TIME);
            }
        }

        // 将评论id转为数组
        $reply_ids = explode(',', $reply_ids);

        $per_page = 15;// 当前文章评论每页显示数量

        // 去除数组最后一个元素
        array_pop($reply_ids);
        // 统计有多少回复
        $total = count($reply_ids);
        $data_list = getPaginatorData($total, $page, $per_page);

        //获取分页后的评论id数组
        $comment_reply = array_slice($reply_ids, $data_list['start'], $per_page);

        unset($data_list['start']);
        unset($data_list['end']);
        $temp = [];
        // 根据当前页评论id获取所需的评论内容
        if (!empty($comment_reply))
        {
            $ac_ids = [];

            // 获取缓存回复内容,根据回复id
            foreach ($comment_reply as $ac_id)
            {
                if ($this->cache_on >= 1)
                {
                    $temp[$ac_id] = Cache::get(self::COMMENT_REPLY . $ac_id);// 获取回复内容
                } else
                {
                    $temp[$ac_id] = false;
                }
                // 评论内容未缓存，等待从数据库中获取
                if ($temp[$ac_id] === false)
                {
                    $ac_ids[] = (int)$ac_id;
                    // 先删除，避免后面查询不到数据时，无法处理当前值
                    unset($temp[$ac_id]);
                }
            }
            // 从数据库获取评论内容
            if (!empty($ac_ids))
            {
                try
                {
                    $replys = $this
                        ->alias('cr')
                        ->field('cr.id,cr.create_time,cr.content,cr.aid,cr.pid,a.title,
                        u.nickname,u.avatar,
                        u1.nickname nickname1,u1.avatar avatar1,ac.content content1,
                        u2.nickname nickname2,u2.avatar avatar2,cr2.content content2')
                        ->join('wechatadmin.system_article_comment ac', 'cr.comment_id=ac.id', 'LEFT')
                        ->join('wechat_backup_07_18_14_43_00.app_user u1', 'ac.ucid=u1.uc_id', 'LEFT')
                        ->join('wechatadmin.system_comment_reply cr2', 'cr.pid=cr2.id', 'LEFT')
                        ->join('wechat_backup_07_18_14_43_00.app_user u2', 'cr2.ucid=u2.uc_id', 'LEFT')
                        ->join('wechatadmin.system_article a', 'cr.aid=a.id', 'LEFT')
                        ->join('wechat_backup_07_18_14_43_00.app_user u', 'cr.ucid=u.uc_id', 'LEFT')
                        ->where(['cr.id' => ['in', $ac_ids]])
                        ->where("u.forbidden=0 AND cr.status=0 AND ((cr.pid=0 AND ac.ucid='{$uc_id}' AND ac.status=0) OR (cr.pid>0 AND cr2.ucid='{$uc_id}' AND cr2.status=0))")
                        ->order('cr.id DESC')
                        ->selectOrFail();

                    $replys = json_decode(json_encode($replys, true), true);
                }
                catch (\Exception $e)
                {
                    $replys = [];
                }
                if (!empty($replys))
                {
                    foreach ($replys as $a)
                    {
                        $a['content'] = htmlspecialchars_decode($a['content']);
                        $a['content1'] = htmlspecialchars_decode($a['content1']);
                        $a['content2'] = htmlspecialchars_decode($a['content2']);
                        // 将评论内容缓存
                        if ($this->cache_on >= 1)
                        {
                            Cache::set(self::COMMENT_REPLY . $a['id'], $a, self::CACHE_TIME);
                        }
                        // 将数据库查出来的内容 写入到数组中为空的部分
                        $temp[$a['id']] = $a;
                    }
                }
            }
        }

        foreach ($temp as $item)
        {
            $data_list['data'][] = $item;
        }

        return $data_list;
    }

    /**
     * 获取当前回复的上级名称 -- 根据回复id
     * @param array $map
     * @return array|bool|mixed|\PDOStatement|string|\think\Model
     */
    public function getReplylevelName($map = [])
    {
        $reply_id = $map['reply_id'];
        $reply_pid = $map['reply_pid'];

        $new_nickname = false;

        if ($this->cache_on >= 1)
        {
            $new_nickname = Cache::get(self::REPLY_LEVEL_NICKNAME . $reply_id);
        }

        if ($new_nickname === false)
        {
            try
            {
                $new_nickname = $this
                    ->alias('cr')
                    ->join('wechat_backup_07_18_14_43_00.app_user u', 'u.uc_id=cr.ucid', "INNER")
                    ->field('nickname')
                    ->where("cr.id=$reply_pid AND u.forbidden=0")
                    ->findOrFail();
            }
            catch (\Exception $e)
            {
                $new_nickname = [];
            }

            $new_nickname = json_decode(json_encode($new_nickname, true), true);
            if ($this->cache_on >= 1)
                Cache::set(self::REPLY_LEVEL_NICKNAME . $reply_id, $new_nickname, self::CACHE_TIME);
        }

        return $new_nickname;
    }

    /**
     * 获取用户回复的未读数据
     * @param array $map
     * @return array|bool|false|mixed|\PDOStatement|string|\think\Collection
     * @throws \Exception
     */
    public function getUnReadReply($map = [])
    {
        $replyModel = new \app\common\cachemodel\ArticleCommentReply();
        $reply_ids = $replyModel->getUserReplyMeFromCache($map['uid']);
        $read_ids = $replyModel->getUserReadReply($map['uid']);
        return array_diff($reply_ids, $read_ids);

        $ucid = $map['ucid'];
        $uid = $map['uid'];

        $data = false;
        if ($this->cache_on >= 1)
        {
            $data = Cache::get('read_reply_' . $uid);
        }
        if ($data === false)
        {
            try
            {
                $data = $this
                    ->alias('cr')
                    ->field('cr.id,ur.reply_id')
                    ->join('wechat_backup_07_18_14_43_00.app_user_reply ur', 'cr.id=ur.reply_id', 'LEFT')
                    ->where('cr.ucid', $ucid)
                    ->order('cr.id DESC')
                    ->select();
                $data = json_decode(json_encode($data, true), true);
            }
            catch (\Exception $e)
            {
                $data = [];
            }
            if ($this->cache_on >= 1)
            {
                Cache::set(self::READ_REPLY . $uid, $data, self::CACHE_TIME);
            }
        }
        return $data;
    }

    /**
     * 添加回复
     * @param array $userInfo
     * @param array $map
     * @param bool $complainSwitch
     * @return array|\PDOStatement|string|\think\Model
     * @throws \GuzzleHttp\Exception\GuzzleException
     * @throws \app\common\lib\exception\ApiException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function add_reply(array $userInfo, $map = [], $complainSwitch = true)
    {
        $data = [
            'comment_id' => $map['comment_id'],
            'pid' => $map['pid'],
            'content' => $map['content'],
            'uid' => (int)$userInfo['id'],
            'status' => 0   // 状态 0 正常 -1 删除
        ];
        $res = (new \app\common\cachemodel\ArticleCommentReply())->addCommentReply($userInfo, $data, $complainSwitch);

        if (!$res['status'])
        {
            throw new ApiException($res['msg'], 200, config('code.error'));
        }

        return [
            'id' => (int)$res['id'],
            'content' => $map['content'],
            'status' => 0,
            'create_time' => request()->time(),
            'pid' => $map['pid'],
            'nickname1' => $userInfo['nickname'],
            'avatar' => $userInfo['avatar'],
            'nickname2' => $map['pid'] ? $res['nickname2'] : null,
            'uid' => $data['uid'],
            'crid' => (int)$res['id'],
        ];

        $id = $map['aid']; //文章id
        $commentid = $map['comment_id'];  // 评论id
        $pid = $map['pid'];  // 回复上级id
        $content = $map['content']; //回复的内容
        $uc_id = $map['ucid'];
        $uid = $map['uid'];

        try
        {
            $reply = $this
                ->where(['aid' => $id, 'comment_id' => $commentid, 'ucid' => $uc_id, 'content' => $content, 'pid' => $pid, 'status' => 0, 'create_time' => $map['create_time']])
                ->findOrFail();
        }
        catch (\Exception $e)
        {
            $reply = [];
        }
        // 非重复回复  发表回复
        if (!$reply || empty($reply))
        {
            if ($rid = $this->insertGetId($map))
            {

                try
                {
                    $this->table('wechatadmin.system_article_comment')->where(['id' => $commentid, 'aid' => $id])->setInc('reply');
                }
                catch (\Exception $e)
                {
//
                }
                // 针对评论的回复
                if ($pid == 0)
                {
                    try
                    {
                        $reply = $this->alias('cr')
                            ->field('cr.id,cr.content,cr.status,cr.create_time,
                        cr.pid,u.nickname nickname1,u.avatar,u2.nickname nickname2,u2.id uid')
                            ->join('wechat_backup_07_18_14_43_00.app_user u', 'u.uc_id=cr.ucid', 'INNER')
                            ->join('wechatadmin.system_article_comment ac', 'ac.id=cr.comment_id', 'INNER')
                            ->join('wechat_backup_07_18_14_43_00.app_user u2', 'u2.uc_id=ac.ucid', 'INNER')
                            ->where(['cr.id' => $rid])
                            ->findOrFail();
                    }
                    catch (\Exception $e)
                    {
                        $reply = [];

                    }
                } // 针对回复的回复
                else
                {
                    try
                    {
                        $reply = $this->alias('cr')
                            ->field('cr.id,cr.content,cr.status,cr.create_time,
                        cr.pid,u.nickname nickname1,u.avatar,u2.nickname nickname2,u2.id uid')
                            ->join('wechatadmin.system_comment_reply cr2', 'cr.pid=cr2.id', 'INNER')
                            ->join('wechat_backup_07_18_14_43_00.app_user u', 'u.uc_id=cr.ucid', 'INNER')
                            ->join('wechat_backup_07_18_14_43_00.app_user u2', 'u2.uc_id=cr2.ucid', 'INNER')
                            ->findOrFail($rid);
                    }
                    catch (\Exception $e)
                    {
                        $reply = [];
                    }
                }
                if ($this->cache_on >= 1)
                {
                    Cache::rm(self::COMMENT_REPLY_ID . $commentid); //根据评论id
                    Cache::rm(self::USER_REPLY_ID . $uid); //根据评论id
                }


            }
        }
        $reply['content'] = isset($reply['content']) ? htmlspecialchars_decode($reply['content']) : '';
        $reply['crid'] = $rid;
        return $reply;
    }
}
